#ifndef _RDB_DRIVER_INTERFACE_H_
#define _RDB_DRIVER_INTERFACE_H_

#include <buildspec.h>
#include <GSTenums.h>
#include <Client/ClientUtils/Network/AbstractDataTable.h>
#include <Client/ClientUtils/Network/NetworkInterface.h>
#include <Client/ClientUtils/Network/RDBExceptions.hpp>

#include <string>

namespace GST {

namespace ClientUtils {

//-------------------------- class of headerfile --------------------------------

	struct StatementBuilder
	{
		std::vector<std::string> statements;
		void appendStatment( const std::string & sqlStatement )
		{
			this->statements.push_back( sqlStatement );
		}
	};

	/**
	 * Interface class handle connections to relational database
	 */
	class GST_API_EXPORT RDBDriverInterface
	{
	public:
		RDBDriverInterface(HostPtr host, const std::string& dbname);
		virtual ~RDBDriverInterface() {}

		///@name RDB interface
		//@{
		virtual void connect() = 0;
		virtual void disconnect() = 0;
		virtual bool isConnected() = 0;
		virtual int getPID() = 0;
		virtual std::string getEndpoint() const;
		virtual std::string getUser() const;
		virtual std::string getUrl() const;
		virtual long getPort() const;
		virtual std::string getDB() const;
		virtual void exec(const std::string & sqlStatement) = 0;
		virtual AbstractDataTablePtr exec_returning(const std::string & sqlStatement) = 0;
		virtual TableAttributeDescListPtr ListTableAttributeDescs(const std::string& tableName) = 0;
		virtual std::string sqlesc(const std::string& param) const = 0;
		virtual std::string asUnquotedIdentifier(const std::string& identifier) const = 0;
		/**
		* Constructs a bulk of statements to be run in one GST::ClientUtils::RDBDriverInterface::exec() call.
		* If the call of exec() fails (e.g. by a syntax error, a constraint error etc.) caused by one of the statements nothing is changed in db.
		*/
		virtual std::string ConcatenateStatements( const StatementBuilder & statements ) const = 0;
		//@}

		///@name shared code by derived
		//@{
		void setHost(HostPtr host);
		HostPtr getHost()const {return host;}
		void setDB(const std::string& dbname);
		virtual void connect(HostPtr h, const std::string dbname);
		//@}

		///@name local helpers
		//@{
		std::string quote_ident(const std::string & identifer) const;
		//@}

	protected:
		///@name members
		//@{
		HostPtr host;
		std::string dbname;
		//@}
	};

	//global typedefs:
	typedef boost::shared_ptr<RDBDriverInterface> RDBInterfacePtr;

} //of ns ClientUtils
} //of ns GST

#endif //_RDB_DRIVER_INTERFACE_H_